package com.spz.demo.singleboot.util;

import com.spz.demo.singleboot.vo.Response;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 文件操作工具类
 * @author zp
 * @date 2018/3/6
 */
@Data
@Slf4j
@Component
public class FileUtil {

    // 前端访问根url
    @Value("${custom.upload.url}")
    private String url;

    // 服务器存放根目录，数据库内只存放文件路径的相对路径
    @Value("${custom.upload.rootPath}")
    private String rootPath;

    // 系统默认头像路径
    @Value("${custom.upload.defaultAvatar}")
    private String defaultAvatar;

    // 相对路径，图片目录
    public static final String RELATIVE_PATH_IMAGE = "/image/";

    /**
     * 单文件上传
     * 上传完成后的文件全路径为：rootPath + relativePath
     * 上传完成后的文件访问路径为：url + relativePath
     * @param file
     * @param relativePath 相对路径
     * @param fileName 文件名，附带后缀名
     * @return
     */
    public Response<Boolean> fileUpload(MultipartFile file,
                                        String relativePath,
                                        String fileName){
        if(url == null || url.equals("")){
            return Response.error("url为空，请检查配置文件",Boolean.FALSE);
        }
        String fullPath = rootPath + "/" +relativePath + "/";
        if (!file.isEmpty()) {
            try {
                // 建立目录
                File dir = new File(fullPath);
                if (!dir.exists()){
                    dir.mkdirs();
                }
                // 查找是否有同名文件
                File[] files = dir.listFiles();
                String hasFileName = "";
                for(int index = 0; index < files.length; index++){
                    hasFileName = files[index].getName();
                    if(fileName.equals(hasFileName)){//指定目录中已经有同名文件
                        log.error("保存文件出错：指定目录中已经有同名文件");
                        return Response.error("保存文件出错：指定目录中已经有同名文件",Boolean.FALSE);
                    }
                }
                // 保存文件
                File serverFile = new File(fullPath + fileName);
                file.transferTo(serverFile);//保存文件
            } catch (Exception e) {
                log.error("保存文件出错：" + e.getMessage());
                return Response.error("保存文件出错：" + e.getMessage(),Boolean.FALSE);
            }
        } else {//文件为空
            log.error("保存文件出错：文件内容为空");
            return Response.error("保存文件出错：文件内容为空",Boolean.FALSE);
        }
        return Response.ok(Boolean.TRUE);
    }

    /**
     * 删除单个文件
     * @param filePath : 待删除文件的路径
     * @return
     * @throws Exception
     */
    public boolean deleteFile(String filePath){
        File file = new File(filePath);
//        if(!file.isFile()){
//            return false;
//        }
        if( !file.exists()){//文件不存在，则默认已删除
            return true;
        }
        return file.delete();
    }

    /**
     * 将文本文件中的内容读入到buffer中
     * @param buffer buffer
     * @param filePath 文件路径
     * @throws IOException 异常
     * @author cn.outofmemory
     * @date 2013-1-7
     */
    public static void readToBuffer(StringBuffer buffer, String filePath) throws IOException {
        InputStream is = new FileInputStream(filePath);
        String line; // 用来保存每行读取的内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        line = reader.readLine(); // 读取第一行
        while (line != null) { // 如果 line 为空说明读完了
            buffer.append(line); // 将读到的内容添加到 buffer 中
            buffer.append("\n"); // 添加换行符
            line = reader.readLine(); // 读取下一行
        }
        reader.close();
        is.close();
    }

    /**
     * 读取文本文件内容
     * @param filePath 文件所在路径
     * @return 文本内容
     * @throws IOException 异常
     * @author cn.outofmemory
     * @date 2013-1-7
     */
    public static String readFile(String filePath) throws IOException {
        StringBuffer sb = new StringBuffer();
        readToBuffer(sb, filePath);
        return sb.toString();
    }

    /**
     * 下载文件到指定目录
     * 来源：http://www.cnblogs.com/x_wukong/p/4434246.html
     * @param urlStr
     * @param fileName
     * @param savePath
     * @throws IOException
     */
    public static boolean  downLoadFileFromUrl(String urlStr,String fileName,String savePath){
        URL url = null;
        InputStream inputStream = null;
        FileOutputStream fos = null;
        try{
            url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            //设置超时间为3秒
            conn.setConnectTimeout(3*1000);
            //防止屏蔽程序抓取而返回403错误
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            //得到输入流
            inputStream = conn.getInputStream();
            //获取自己数组
            byte[] getData = readInputStream(inputStream);
            //文件保存位置
            File saveDir = new File(savePath);
            if(!saveDir.exists()){
                saveDir.mkdirs();
            }
            File file = new File(savePath + "/" + fileName);
            if(!file.exists()){
                file.createNewFile();
            }
            fos = new FileOutputStream(file);
            fos.write(getData);
        }catch (Exception e){
            log.error(e.getMessage());
            return false;
        }finally {
            try{
                if(fos!=null){
                    fos.close();
                }
                if(inputStream!=null){
                    inputStream.close();
                }
            }catch(Exception e1){
                log.error(e1.getMessage());
                return false;
            }
        }
        return true;
    }

    /**
     * 生成文件名
     * @return
     */
    public static String createFileName(){
        return new SimpleDateFormat("YYYYMMDDhhmmssSSS").format(new Date()) +
                "-" +
                StringUtil.getRandomString(8);
    }

    /**
     * 从输入流中获取字节数组
     * @param inputStream
     * @return
     * @throws IOException
     */
    private static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

//    public static void main(String[] args)throws Exception{
//            downLoadFileFromUrl("http://thirdwx.qlogo.cn/mmopen/PiajxSqBRaEJicQbqotg8CSyqicib9B5wjCfDwGZnhcbem5WW7loTQI4ldQaZ25b8PQV1duu5bc8M4NvLCtmYhDmhQ/132",
//                    "xxx.jpg","e:/etc/");
//    }
}